package com.xc.round2Assessment.petStore.pet.facade;

import com.xc.round2Assessment.petStore.exception.AnimalNotFoundException;
import com.xc.round2Assessment.petStore.pet.factory.ContextFactory;
import com.xc.round2Assessment.petStore.pet.factory.StrategyFactory;
import com.xc.round2Assessment.petStore.pet.strategy.AnimalStrategy;
import com.xc.round2Assessment.petStore.pet.strategyContext.BuyContext;
import com.xc.round2Assessment.petStore.pet.strategyEnum.StrategyEnum;

/**
 * @author Xc
 * @version 1.0
 * 门面模式的外观 : Facade
 * 对内部的策略模式进行封装
 * 后续所有需要购买动物的话, 只需要调用 buy 就好了
 */
public class StrategyFacade {

    /**
     * @param choice 要购买的动物的品种 : 0 鸟, 1 猫， 2狗
     * @return 购买一只该动物需要的价钱
     */
    public static AnimalStrategy buy(Integer choice) {
        // 先获取 策略枚举
        StrategyEnum strategyEnum = getStrategyEnum(choice);
        if (strategyEnum == null) {
            throw new AnimalNotFoundException("您所需要的动物不存在~");
        }

        /* 获取对象尽量用工厂类, 单例模式(或享元模式)。 减少频繁地进行对象的创建、频繁的 minorGC*/
        // todo 先把 策略工厂 与 策略上下文工厂， 创建起来

        // 用策略工厂， 以策略枚举为参数， 通过反射获取策略对象
        AnimalStrategy animalStrategy = StrategyFactory.getAnimalStrategy(strategyEnum);

        // 用策略上下文工厂， 以策略对象为参数， 获取上下文对象
        BuyContext context = ContextFactory.getContext(animalStrategy);

        // todo 后续如果要为购买添加其他的功能可以考虑加入装饰器模式 (如多次、大量购买的优惠， 购买以后的积分等等)
        return context.execute(choice);
    }

    private static StrategyEnum getStrategyEnum(int choice) {
        switch(choice) {
            case 0:
                return StrategyEnum.BirdStrategy;
            case 1:
                return StrategyEnum.CatStrategy;
            case 2:
                return StrategyEnum.DogStrategy;
            default:
                return null;
        }
    }
}
